package ace.tool.generate.code.impl.resolver.scheme.resolver.core;

import ace.tool.generate.code.impl.manager.common.EntityModelManager;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.core.EntityClassInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.core.resources.GraphqlDtoFileInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.core.resources.GraphqlInputFileInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.core.resources.GraphqlSchemaAutoGenerateFileInfo;
import ace.tool.generate.code.impl.resolver.scheme.model.bo.core.resources.model.dto.*;
import ace.tool.generate.code.impl.resolver.scheme.model.dto.ProjectInfo;
import ace.tool.generate.code.impl.service.model.input.GenerateInput;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.apache.commons.text.StringSubstitutor;
import org.apache.commons.text.WordUtils;

/**
 * @author caspar
 * @date 2023/11/17 10:34
 */
@RequiredArgsConstructor
public class GraphqlSchemaAutoGenerateFileInfoResolver {
  private final GenerateInput input;
  private final List<EntityClassInfo> entityClassInfo;
  private final List<GraphqlDtoFileInfo> graphqlDtoFileInfos;
  private final List<GraphqlInputFileInfo> graphqlInputFileInfos;
  private final ProjectInfo coreProjectInfo;
  private final EntityModelManager entityModelManager = new EntityModelManager();

  public GraphqlSchemaAutoGenerateFileInfo resolve() {

    return GraphqlSchemaAutoGenerateFileInfo.builder()
        .fileName(input.getGraphqlSchemaFileName())
        .fileFullName(this.getFileFullName())
        .model(this.getModel())
        .build();
  }

  private GraphqlSchemaAutoGenerateModel getModel() {
    return GraphqlSchemaAutoGenerateModel.builder().fields(this.getFields()).build();
  }

  private List<GraphqlSchemaAutoGenerateField> getFields() {
    return this.entityClassInfo.stream().map(this::getField).collect(Collectors.toList());
  }

  private GraphqlSchemaAutoGenerateField getField(EntityClassInfo entityClassInfo) {
    GraphqlDtoFileInfo graphqlDtoFileInfo =
        this.entityModelManager.getGraphqlDtoFileInfo(
            graphqlDtoFileInfos, entityClassInfo.getEntityModelId());
    GraphqlInputFileInfo graphqlInputFileInfo =
        this.entityModelManager.getGraphqlInputFileInfo(
            graphqlInputFileInfos, entityClassInfo.getEntityModelId());
    String type =
        GraphqlTypeResolver.builder()
            .type(entityClassInfo.getModel().getEntityIdTypeClass())
            .idFlag(false)
            .build()
            .resolve();
    return GraphqlSchemaAutoGenerateField.builder()
        .dtoModelName(graphqlDtoFileInfo.getModel().getName())
        .inputModelName(graphqlInputFileInfo.getModel().getName())
        .idType(type)
        .methodNamePrefix(this.getMethodNamePrefix(entityClassInfo))
        .build();
  }

  private String getMethodNamePrefix(EntityClassInfo entityClassInfo) {
    return WordUtils.uncapitalize(entityClassInfo.getModel().getClassName());
  }

  private String getFileFullName() {
    Map<String, String> data = new HashMap<>();
    data.put("fileName", input.getGraphqlAutoSchemaFileName());
    data.put("sourceCodeRootDir", coreProjectInfo.getResourcesRootDir());
    data.put("rootDirPrefix", input.getGraphqlSchemaRootDirPrefix());
    return StringSubstitutor.replace("${sourceCodeRootDir}/${rootDirPrefix}/${fileName}", data);
  }
}
